#ifndef CHESSDATA_H
#define CHESSDATA_H

#include <QList>
#include <QHash>
#include "sendbus.h"
#include "consumerobj.h"

class PieceData{

public:
    PieceData();
    PieceData(int id,QString name,int type);
    void setPos(double cx,double cy);

    void setKind(int kind);


    PieceData(const PieceData& pd);

    ~PieceData();

    //棋子名称
    QString textName;
    //棋子唯一id
    int id;
    //棋子颜色 0黑色 1 红色
    int type;

    //棋子相对棋盘位置(取整)
    double cx;
    double cy;

    //棋子种类: 1 车  2 马 3 炮 4 相 5 士 6 将 7卒
    int kind;



    bool operator==(const PieceData& pd);


};


class ChessData :public ConsumerObj
{
public:



    ChessData();
    ~ChessData();


    //重置棋盘,棋子归位,开始新游戏
    void resetGame(bool isRed);

    void setSpos(double sx,double sy);

    void setRd(double r,double d);

    void saveSelectPieceInfo(int id,int col,int row,int side,int type);

    void cancelSelectPiece();

    void printTableBoard();

    //保存棋子移动信息
    void saveMoveInfo(int oldCol,int oldRow,int col,int row);

    //计算选中棋子的移动范围
    void calcCanMovePos();

    //计算该点有无车,马,炮,过河兵 杀 ,side 主杀方
    bool calcPosCankill(int pcol,int prow,int side);


    //判断选中的棋子是否可以移动到指定位置,指定位置有不同颜色的棋子,则吃掉
    bool canMoveToPos(int desCol,int desRow);

    bool canEatPiece(int desCol, int desRow);


    //记录步数
    void saveStepCount();

    //游戏是否开始
    bool gameStart=false;

    //棋盘初始位置
    double sx;
    double sy;
    //棋子半径
    double r;
    //棋盘格子长度
    double d;

    //游戏总步数
    int step=0;

    //轮到哪一方 0黑色 1 红色
    int sideStep=1;

    //被选择的棋子id
    int selectId=-1;
    //被选中的棋子位置
    int col;
    int row;
    //0黑色 1 红色
    int selectSide;

    //选中的棋子类型
    int selType;

    //被选中棋子可以移动的位置
    QList<int*>* canMovePos;


    const QString pnames[32]={"车","马","炮","士","象","将","车","马","炮","士","象","卒","卒","卒","卒","卒",
                        "车","马","炮","仕","相","帅","车","马","炮","仕","相","兵","兵","兵","兵","兵"};


    // 0 红色棋子在下方  1 黑色棋子在下方
    int sideBelow=0;

    //黑色棋子在下面
    const double blackPos[32][2]={
        {0,9},{1,9},{1,7},{3,9},{2,9},{4,9},{8,9},{7,9},{7,7},{5,9},{6,9},{0,6},{2,6},{4,6},{6,6},{8,6},
        {0,0},{1,0},{1,2},{3,0},{2,0},{4,0},{8,0},{7,0},{7,2},{5,0},{6,0},{0,3},{2,3},{4,3},{6,3},{8,3}
    };

    //红色棋子在下面
    const double redPos[32][2]={{0,0},{1,0},{1,2},{3,0},{2,0},{4,0},{8,0},{7,0},{7,2},{5,0},{6,0},{0,3},{2,3},{4,3},{6,3},{8,3},
                                  {0,9},{1,9},{1,7},{3,9},{2,9},{4,9},{8,9},{7,9},{7,7},{5,9},{6,9},{0,6},{2,6},{4,6},{6,6},{8,6}};

    //棋子种类: 1 车  2 马 3 炮 4 相 5 士 6 将 7卒
    const int kinds[32]={1,2,3,5,4,6,1,2,3,5,4,7,7,7,7,7,
                         1,2,3,5,4,6,1,2,3,5,4,7,7,7,7,7};


    //棋盘表,每一个位置代表一个棋子

    const static int max_col=8;
    const static int max_row=9;
    PieceData* boardTable[max_col+1][max_row+1];


    //游戏中棋盘上剩余的棋子,棋子位置的hash映射,根据位置找到棋子 key=cx_cy
     QHash<QString,PieceData>* pieceHash;


    //死亡的棋子
    QList<PieceData>* deadPieces=nullptr;

    //信号发射
    SendBus* sendBus=new SendBus();


 public slots:


     //设置游戏开始
    void setGameStart(int value);

    //设置优先方
     void setGameBelow(int value);


private:
    void calcElephantPos(QList<int*>* res,int minlimtRow,int maxlimitRow);
    void calcAdvisorPos(QList<int*>* res,int minlimitrow,int maxlimitrow,int minlimitcol,int maxlimitcol);
    void calcKingPos(QList<int*>* res,int minlimitrow,int maxlimitrow,int minlimitcol,int maxlimitcol);
    //side=1 上走 side=0 下走
    void calcPawnPos(QList<int*>* res,int midRow,int side);

    void deleteDeadPieces();



};





#endif // CHESSDATA_H
